package com.pureut.storage.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pureut.storage.domain.BarCodePrint;
import com.pureut.storage.domain.PublicMaterial;
import com.pureut.storage.domain.WmsStockInfo;
import com.pureut.storage.dto.BarCodePrintingDto;
import com.pureut.storage.dto.PrintDto;
import com.pureut.storage.dto.UnitConversionDto;
import com.pureut.storage.mapper.BarCodePrintingMapper;
import com.pureut.storage.mapper.PublicMaterialMapper;
import com.pureut.storage.mapper.PurchaseReceiptMapper;
import com.pureut.storage.mapper.WmsStockInfoMapper;
import com.pureut.storage.service.BarCodePrintingService;
import com.pureut.storage.service.WmsStockInfoService;
import com.pureut.storage.util.UnitUtil;
import com.pureut.storage.vo.BarCodePrintVo;
import com.pureut.storage.vo.PrintVo;
import com.sale.common.core.constant.CacheNames;
import com.sale.common.core.exception.GlobalException;
import com.sale.common.mybatis.core.page.PageQuery;
import com.sale.common.mybatis.core.page.TableDataInfo;
import com.sale.common.redis.utils.CacheUtils;
import com.sale.common.satoken.utils.LoginHelper;
import com.sale.system.api.RemoteCodeService;
import com.sale.system.api.RemoteCodingService;
import com.sale.system.api.RemoteUnitService;
import com.sale.system.api.domain.SysAuxiliary;
import com.sale.system.api.domain.SysDictData;
import com.sale.system.api.domain.dto.SysApiCategoryDto;
import com.sale.system.api.model.MaterialUnitDto;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Nonnull;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 条码打印实现层
 *
 * @author: CM
 * @date: 2023/4/4  14:30
 */
@Service
@RequiredArgsConstructor
public class BarCodePrintingServiceImpl extends ServiceImpl<BarCodePrintingMapper, BarCodePrint> implements BarCodePrintingService {

    @Nonnull
    private BarCodePrintingMapper barCodePrintingMapper;

    @DubboReference
    RemoteCodeService remoteCodeService;


    /**
     * 库存Service
     */
    @Nonnull
    private WmsStockInfoService wmsStockInfoService;

    @Nonnull
    private PurchaseReceiptMapper purchaseReceiptMapper;

    @Nonnull
    private RemoteUnitService remoteUnitService;

    @Nonnull
    private WmsStockInfoMapper wmsStockInfoMapper;

    @Nonnull
    private PublicMaterialMapper publicMaterialMapper;

    @DubboReference
    RemoteCodingService remoteCodingService;

    @Resource
    UnitUtil unitUtil;


    /**
     * 条码打印列表
     *
     * @param barCodePrintVo
     * @return
     */
    @Override
    public TableDataInfo<BarCodePrintingDto> getList(BarCodePrintVo barCodePrintVo, PageQuery pageQuery) throws Exception {
        Page<BarCodePrintingDto> list = barCodePrintingMapper.selectPrintList(pageQuery.build(), barCodePrintVo);

        //根据字典查出收发类型
        List<SysDictData> printType = CacheUtils.get(CacheNames.SYS_DICT, "print_type");
        Map<String, String> printMap = printType.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //单位集合
        Map<String, MaterialUnitDto> unitByCodeToMap = remoteUnitService.getUnitByCodeToMap();

        for (BarCodePrintingDto barCodePrintingDto : list.getRecords()) {
            barCodePrintingDto.setPrintTypeDict(printMap.get(barCodePrintingDto.getPrintType()));
            //单位转换
            String s = unitUtil.unitC(barCodePrintingDto.getMaterialCode(),
                String.valueOf(barCodePrintingDto.getNetWeight()),
                barCodePrintingDto.getMaterialId(),
                unitByCodeToMap.get(String.valueOf(barCodePrintingDto.getMaterialUnit())).getUnitName());
            barCodePrintingDto.setUnitConversion(s);

            //辅助属性
            List<SysAuxiliary> statsArray = CacheUtils.get(CacheNames.SYS_GINSENG + "_" + barCodePrintingDto.getTenantId(), String.valueOf(barCodePrintingDto.getMaterialId()));
            barCodePrintingDto.setAuxiliaryAttribute(statsArray);

            barCodePrintingDto.setMaterialUnit(barCodePrintingDto.getMaterialUnit());
            //单位
            if (barCodePrintingDto.getMaterialUnit() != null) {
                barCodePrintingDto.setMaterialUnitDict(unitByCodeToMap.get(String.valueOf(barCodePrintingDto.getMaterialUnit())).getUnitName());
            }
        }

        return TableDataInfo.build(list);
    }

    /**
     * 来料打印
     *
     * @param materialNumber
     * @return
     */
    @Override
    public PrintDto getMaterialNumber(String materialNumber, String type) {
        String printNumber;
        //判断输入的条码是否为拆包条码
        int count = 0;
        for (int i = 0; i < materialNumber.length(); i++) {
            if (materialNumber.charAt(i) == '-') {
               count++;
            }
        }
        if (count > 1) {
            //截取拆包之后的号码
            printNumber = materialNumber.substring(0, materialNumber.lastIndexOf("-"));
        } else {
            printNumber = materialNumber;
        }


        PrintDto printDto = barCodePrintingMapper.selectSuppliedMaterials(printNumber);

        //单位集合
        Map<String, MaterialUnitDto> unitByCodeToMap = remoteUnitService.getUnitByCodeToMap();

        if (printDto == null) {
            throw new GlobalException("该条码不存在,请输入正确的号码");
        } else {
            //单位
            if (printDto.getMaterialUnit() != null) {
                printDto.setMaterialUnitDict(unitByCodeToMap.get(printDto.getMaterialUnit()).getUnitName());
            }

            //辅助属性
            List<SysAuxiliary> statsArray = CacheUtils.get(CacheNames.SYS_GINSENG + "_" + printDto.getTenantId(), String.valueOf(printDto.getMaterialId()));
            printDto.setAuxiliaryAttribute(statsArray);
            return printDto;
        }
    }

    /**
     * 打印
     *
     * @param printVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public PrintVo print(PrintVo printVo) throws Exception {
        String cgrkdynum = "";
        //如果是条码添加校验是否配置了单据
        if ("2".equals(printVo.getPrintType())) {
            cgrkdynum = remoteCodeService.authorityCoding("warehouse:inside:barcodePrinting:list");
            if (cgrkdynum == null || "".equals(cgrkdynum)) {
                throw new GlobalException("该单据未进行配置,无法生成单据编码");
            }
        }

        PublicMaterial publicMaterial = publicMaterialMapper.selectOne(new QueryWrapper<PublicMaterial>()
            .lambda().eq(PublicMaterial::getMaterialCode, printVo.getMaterialCode()));

        BarCodePrint barCodePrint = new BarCodePrint();
        BeanUtils.copyProperties(printVo, barCodePrint);
        barCodePrint.setConnectDoc(printVo.getWsiConnectNum());
        barCodePrint.setNetWeight(String.valueOf(printVo.getNetWeight()));
        barCodePrint.setDeptId(LoginHelper.getDeptId());
        barCodePrint.setCreateTime(new Date());
        barCodePrint.setCreateUser(LoginHelper.getUsername());
//        barCodePrint.setMaterialUnit(printVo.getMaterialUnit());


        if ("2".equals(printVo.getPrintType())) {
            barCodePrint.setMaterialNumber(cgrkdynum);

        }

        boolean save = save(barCodePrint);

        if (save) {
            //判断打印类型是补打还是手动添加
            if ("2".equals(printVo.getPrintType())) {
                //获取物料类别
                SysApiCategoryDto data = remoteCodingService.getByCode(printVo.getMaterialCode()).getData();

                WmsStockInfo wmsStockInfo = new WmsStockInfo();
                wmsStockInfo.setWsiMaterialNumber(cgrkdynum);//物料号码
                wmsStockInfo.setWsiMaterialCode(printVo.getMaterialCode());//物料编码
                wmsStockInfo.setWsiConnectNum(printVo.getWsiConnectNum());//关联单号
                wmsStockInfo.setWsiMaterialStatus(1);
                wmsStockInfo.setMaterialUnit(publicMaterial.getMaterialUnit());
                if (data.getCategoryId() != null) {
                    wmsStockInfo.setWsiCategory(String.valueOf(data.getCategoryId()));
                    wmsStockInfo.setWsiMaterialType(Long.parseLong(data.getCategoryType()));
                }
                wmsStockInfo.setWsiMaterialNum(1);
                printVo.setMaterialNumber(cgrkdynum);


                //通过关联单号查出供应商编码
                PrintDto printDto = purchaseReceiptMapper.getReceiptInfo(printVo.getWsiConnectNum());
                if (printVo.getSupplierCode() != null) {
                    wmsStockInfo.setWsiSupplierCode(printVo.getSupplierCode());//供应商编码
                }
                if (printVo.getConverterCode() != null) {
                    wmsStockInfo.setWsiConverterCode(printVo.getConverterCode());//加工商编码
                }
                if (printVo.getCustomerCode() != null) {
                    wmsStockInfo.setWsiCustomCode(printVo.getCustomerCode());//客户编码
                }
                wmsStockInfo.setWsiGorssWeight(printVo.getGrossWeight());//毛重
                wmsStockInfo.setWsiNetWeight(printVo.getNetWeight());//净重
                wmsStockInfo.setWsiMaterialBatch(printVo.getMaterialBatch());//批次号
                wmsStockInfo.setWsiProducedDate(printVo.getProductionDate());//生产日期
                wmsStockInfoMapper.insert(wmsStockInfo);
                printVo.setMaterialNumber(cgrkdynum);


            }
        } else {
            throw new GlobalException("打印失败");
        }

        return printVo;


    }

    /**
     * 查询条码打印页面进行条码添加操作数据信息
     *
     * @param materialNumber
     * @param type
     * @return
     */
    @Override
    public BarCodePrintingDto getMaterialNumberByType(String materialNumber, String type) {
        return barCodePrintingMapper.getMaterialNumberByType(materialNumber, type);
    }


}
